package com.xmb.common.service.wx.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.xmb.common.constants.PayStatusEnum;
import com.xmb.common.dao.XmbWechatPaymentOrderMapper;
import com.xmb.common.entity.XmbWechatPaymentOrder;
import com.xmb.common.service.impl.NotifyPayOrderStrategy;
import com.xmb.common.service.impl.NotifyPayOrderStrategyHolder;
import com.xmb.common.service.wx.WxPayNotifyService;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * Created by lyndon on 2019/3/27.
 */
@Service
public class WxPayNotifyServiceImpl implements WxPayNotifyService {
    private static final Logger logger = LoggerFactory.getLogger(WxPayNotifyServiceImpl.class);

    @Resource
    private XmbWechatPaymentOrderMapper paymentOrderMapper;

    /**
     * 支付的签名秘钥
     */
    @Value("${wechat.pay.mchKey}")
    private String mchKey;

    private WxPayService wxPayService;

    @Autowired
    private DefaultMQProducer mqProducer;

    public void payNotify (String xmlData) throws WxPayException{
        logger.info("resultXml:" + xmlData);
        wxPayService = new WxPayServiceImpl();
        WxPayConfig payConfig = new WxPayConfig();
        payConfig.setMchKey(mchKey);
        wxPayService.setConfig(payConfig);
        final WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
        logger.info("支付回调解析结果:resultCode = {},errCodeDesc = {}",notifyResult.getResultCode(),notifyResult.getErrCodeDes() );
        if ("SUCCESS".equals(notifyResult.getResultCode())) {
            // 更新支付订单表
            XmbWechatPaymentOrder wechatPaymentOrder = this.updateWechatPaymentOrder(notifyResult);
            if (wechatPaymentOrder != null) {
                // 通知业务系统
                this.notifyBusiness(wechatPaymentOrder);
            }
        }
    }

    @Transactional
    public XmbWechatPaymentOrder updateWechatPaymentOrder (WxPayOrderNotifyResult notifyResult) {
        XmbWechatPaymentOrder wechatPaymentOrder
                = paymentOrderMapper.selectByMerchantTransactionNo(notifyResult.getOutTradeNo());
        if (wechatPaymentOrder != null) {
            wechatPaymentOrder.setWxTransactionNo(notifyResult.getTransactionId());
            wechatPaymentOrder.setPayStatus(PayStatusEnum.paid.name());
            wechatPaymentOrder.setPayTime(LocalDateTime.parse(notifyResult.getTimeEnd(),
                    DateTimeFormatter.ofPattern(WxPayUnifiedOrderServiceImpl.WX_TIME_PATTERN)));
            paymentOrderMapper.updateByPrimaryKeySelective(wechatPaymentOrder);
        }
        return wechatPaymentOrder;
    }


    /**
     * 通知业务系统处理
     * @param wechatPaymentOrder
     * @return
     */
    private void notifyBusiness(XmbWechatPaymentOrder wechatPaymentOrder) {
        NotifyPayOrderStrategy strategy = NotifyPayOrderStrategyHolder.getSingleton().getStrategy(wechatPaymentOrder.getSenceType());
        if (strategy != null) {
            strategy.notifyBusiness(wechatPaymentOrder);
        }
    }

    /**
     * 获取通知业务系统的消息
     * @param wechatPaymentOrder
     */
    public Message getNotifyBusinessMsg(XmbWechatPaymentOrder wechatPaymentOrder){
        String transType = wechatPaymentOrder.getMerchantTransactionNo().split("_")[1];
        Long senceId = wechatPaymentOrder.getSenceId();
        JSONObject msgObject = new JSONObject(2);
        msgObject.put("transType",transType);
        msgObject.put("senceId",senceId);
        Message sendMsg = new Message("payOrder","shopping",msgObject.toString().getBytes());
        return sendMsg;
    }

    /**
     *  获取需要延迟检查的消息
     * @param wechatPaymentOrder
     */
    public Message getDelayCheckMsg (XmbWechatPaymentOrder wechatPaymentOrder){
        String transType = wechatPaymentOrder.getMerchantTransactionNo().split("_")[1];
        Long senceId = wechatPaymentOrder.getSenceId();
        JSONObject msgObject = new JSONObject(2);
        msgObject.put("transType",transType);
        msgObject.put("senceId",senceId);
        Message sendMsg = new Message("","shopping",msgObject.toString().getBytes());
        sendMsg.setDelayTimeLevel(8); // 延迟5分钟消费
        return sendMsg;
    }

    /**
     * 发送消息
     * @param sendMsg
     */
    public void sendMsg(Message sendMsg) {
        SendResult sendResult = null;
        try {
            sendResult = mqProducer.send(sendMsg);
            logger.info("消息发送响应信息："+sendResult.toString());
        } catch (MQClientException | RemotingException | MQBrokerException | InterruptedException e) {
            e.printStackTrace();
            logger.error("消息发送出现异常："+e.getMessage());
        }
    }

}
